import re
import config
import common
import random
import array

# Step 1: Choose a starting point of MarkovOrder (2 or 3) notes. 
# Choose from list of states that have a non-empty successor list.
# Step 2: Find a note randomly(?) from the list of successors.
# There's scope for improvement(?) here - we can choose to take the
# more likely notes more often. Or choose the next note based on more
# than just the current markov state - like using a pre-defined mood
# (happy, sad, etc) and choosing a high or a low note based on that.
# But as a first step, we can go head and choose the note randomly.
# Step 3: Update the state and repeat 2 until a certain number of
# notes are composed.

SuccessorList = {};
NumVerses = 12; # Num of verses in the composition. 1 Verse = 1 cycle of tala

def ReadAnalytics():
	f = open(config.OutFile,'r');
	for line in f:
		temp = re.split('\s+',line);
		def cutempty(x): return x!="" and x!="\n";
		slist = filter(cutempty, temp[1:]);
		SuccessorList[int(temp[0])] = slist;


def GetNotesFromState(s):
	notes = [];
	for i in range(0,config.MarkovOrder,1):
		temp = config.MarkovOrder - i - 1;
		notes.append(s/common.NumNotes**temp);
		s = s%(common.NumNotes**temp);
	return notes;

def GetStartState():
	global SuccessorList;
	state = SuccessorList.keys()[random.randrange(len(SuccessorList.keys()))]
	state = GetNotesFromState(state);
	return state;

def compose():
	state = GetStartState();
	for x in state:
		print common.NoteRevIndex[x],
	versecount  = 0;
	symcount = config.MarkovOrder; #number of notes in state
	while(versecount < 12):
		if(symcount == 8):
			symcount = 0;
			versecount += 1
			print;
		while (versecount < 12 and symcount < 8): #assuming adi talam for now
			temp = common.FindMarkovMatrixIndex(state);
			if(SuccessorList.has_key(temp)):
				nextnote = SuccessorList[temp][random.randrange(len(SuccessorList[temp]))];
				print common.NoteRevIndex[int(nextnote)],
				state.pop(0);
				state.append(int(nextnote));
				symcount += 1;
				continue;
#			print "<Split>"
			state = GetStartState();
			for x in state:
				print common.NoteRevIndex[x],
				symcount +=1;
				if(symcount == 8):
					versecount += 1;
					symcount = 0;
					print;
	
common.CreateNoteIndex();
ReadAnalytics();
compose();
